﻿using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using RestSharp;

namespace Ymatou.ServiceCenter
{
    /// <summary>
    /// 服务中心，负责统一与服务中心的接口交互
    /// </summary>
    public static class ServiceCenterFacade
    {
        private static void AddHeader(RestRequest request)
        {
            if(request==null)
                return;
            request.AddHeader("ConsumerAppId", Utils.GetConsumerAppId());
            request.AddHeader("ConsumerIp", Utils.LocalIp);
            request.AddHeader("ConsumerAssemblyVersion", Utils.GetAssemblyVersion());
        }

        /// <summary>
        /// 获取服务依赖关系的配置信息
        /// </summary>
        /// <param name="appId">应用编号</param>
        /// <param name="lastUpdateTicks">最后一次更新时间刻度，为null时获取所有服务消费者的应用编号为{AppId}的数据</param>
        /// <returns></returns>
        public static IList<ServiceConfig> GetServiceConfigs(string appId, long? lastUpdateTicks = null)
        {
            if (string.IsNullOrWhiteSpace(appId))
                return null;
            RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
            RestRequest request = new RestRequest
            {
                Resource = "api/Service/GetServiceConfigs?appId={appId}&lastUpdateTicks={lastUpdateTicks}",
                Method = Method.GET
            };
            AddHeader(request);
            request.AddUrlSegment("appId", appId);
            request.AddUrlSegment("lastUpdateTicks", lastUpdateTicks == null ? "" : lastUpdateTicks.ToString());
            IRestResponse restResponse = restClient.Execute(request);
            restResponse.CheckResponse();
            return JsonConvert.DeserializeObject<IList<ServiceConfig>>(restResponse.Content);
        }

        /// <summary>
        /// 获取某个应用服务元数据信息，当最后一次更新时间刻度为null时获取该应用下的所有服务元数据，不为null时则获取变化的数据
        /// </summary>
        /// <param name="appId">应用编号</param>
        /// <param name="lastUpdateTicks">最后一次时间更新刻度</param>
        /// <returns></returns>
        public static IList<ServiceMetadata> GetServiceMetadatas(string appId, long? lastUpdateTicks = null)
        {
            if (string.IsNullOrWhiteSpace(appId))
                return null;
            RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
            RestRequest request = new RestRequest
            {
                Resource = "api/Service/GetServiceMetadatas?appId={appId}&lastUpdateTicks={lastUpdateTicks}",
                Method = Method.GET
            };
            AddHeader(request);
            request.AddUrlSegment("appId", appId);
            request.AddUrlSegment("lastUpdateTicks", lastUpdateTicks == null ? "" : lastUpdateTicks.ToString());
            IRestResponse restResponse = restClient.Execute(request);
            restResponse.CheckResponse();
            return JsonConvert.DeserializeObject<IList<ServiceMetadata>>(restResponse.Content);
        }

        /// <summary>
        /// 批量保存服务元数据信息
        /// </summary>
        /// <param name="serviceMetadatas">服务元数据信息列表</param>
        public static bool SaveServiceMetadatas(IList<ServiceMetadata> serviceMetadatas)
        {
            if (serviceMetadatas == null || serviceMetadatas.Count <= 0)
            {
                Logger.Debug("没有检测到服务元数据");
                return true;
            }

            Logger.Debug("开始上传服务元数据");

            try
            {
                RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
                JsonRequest request = new JsonRequest
                {
                    Resource = "api/Service/SaveServiceMetadatas",
                    Method = Method.POST
                };
                AddHeader(request);
                request.AddJsonBody(serviceMetadatas);
                restClient.ExecuteAsync(request, (response, handle) =>
                {
                    try
                    {
                        response.CheckResponse();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("上传服务元数据异常 ", ex);
                    }
                });
                
            }
            catch (Exception ex)
            {
                Logger.Error("上传服务元数据异常 ", ex);
                return false;
            }

            Logger.Debug("上传服务元数据完成");
            return true;
        }

        

        /// <summary>
        /// 批量保存服务依赖采样信息
        /// </summary>
        /// <param name="samplings">服务依赖采样信息</param>
        public static void SaveServiceDependencySamplings(IList<ServiceDependencySampling> samplings)
        {
            if (samplings == null || !samplings.Any())
                return;

            if (RpcClientConfigManager.GetCurrentClientConfig().EnableSendNullData || samplings.Any(r =>r!=null && r.TotalRequestTimes > 0))
            {
                RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
                JsonRequest request = new JsonRequest
                {
                    Resource = "api/Service/SaveServiceDependencySamplings",
                    Method = Method.POST
                };
                AddHeader(request);
                request.AddJsonBody(samplings);
                IRestResponse restResponse = restClient.Execute(request);
                restResponse.CheckResponse();
            }
        }

        /// <summary>
        /// 获取客户端配置信息
        /// </summary>
        /// <param name="appId">应用编号</param>
        /// <returns></returns>
        public static RpcClientConfig GetRpcClientCfg(string appId)
        {
            if (string.IsNullOrEmpty(appId))
                return RpcClientConfig.DefaultRpcClientConfig;
            try
            {
                RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
                RestRequest request = new RestRequest
                {
                    Resource = "api/service/GetRpcClientCfg/{appId}",
                    Method = Method.GET
                };
                AddHeader(request);
                request.AddUrlSegment("appId", appId);
                IRestResponse restResponse = restClient.Execute(request);
                RpcClientConfig config= JsonConvert.DeserializeObject<RpcClientConfig>(restResponse.Content);
                return config ?? RpcClientConfig.DefaultRpcClientConfig;
            }
            catch (Exception ex)
            {
                Logger.Warn(string.Format("appId:{0},获取客户端配置信息出现异常",appId), ex);
                return RpcClientConfig.DefaultRpcClientConfig;
            }
        }

        /// <summary>
        /// 保存服务依赖数据
        /// </summary>
        /// <param name="dependency">服务依赖统计值采样</param>
        public static void SendFastServiceDependency(ServiceDependencySampling dependency)
        {
            try
            {
                RestClient restClient = new RestClient(Utils.GetServiceCenterHost());
                RestRequest request = new RestRequest
                {
                    Resource = "api/service/SaveServicedependency_Info",
                    Method = Method.POST
                };
                AddHeader(request);
                request.AddJsonBody(dependency);
                IRestResponse restResponse = restClient.Execute(request);
                restResponse.CheckResponse(false);
            }
            catch (Exception ex)
            {
                Logger.Error("发送服务原数据错误 ", ex);
            }           
        }

        /// <summary>
        /// 供服务调用者使用，确定是否使用RPC方式访问服务提供者的接口
        /// </summary>
        /// <returns></returns>
        public static bool EnableUseRpcCall
        {
            get
            {
                return RpcClientConfigManager.GetCurrentClientConfig().EnableUseRpcCall;
            }
        }
    }
}
